package ArithmeticLibrary.Sets;

import ArithmeticLibrary.Elements.ElementGroup;
import ArithmeticLibrary.Util.ArrayOfElementGroup;
import ByteTree.ByteTree;
import Cryptographic.PRG;

/**
 * This class represents a general Group. 
 * It also holds the method randomArray() which generates a random array of 
 * generators of this group.
 * 
 * @author Lea Golan
 */
public abstract class Group {

	/**
	 * Checks if the specified element is in the group.
	 * 
	 * @param element - an element of a group
	 * @return true iff the given element belongs to the group
	 */
	public abstract boolean belong(ElementGroup element); 
	
	/**
	 * Creates a new Group element by encoding message into the group. 
	 * 
	 * @param message - a byte tree representing a group element
	 * @return a new ElementGroup according to parameters extracted from message
	 * @throws Exception - if the byte tree is not appropriately formatted
	 */
	public abstract ElementGroup createElement(ByteTree message) throws Exception; 
	
	/**
	 * Compare this to obj
	 * 
	 */
	public boolean equals(java.lang.Object obj) {
		return false;
	}
	
	/**
	 * @return the underlying field order
	 */
	public abstract java.math.BigInteger getSuperGroupOrder(); 
	
	/**
	 * @return the group generator 
	 */
	public abstract ElementGroup getGroupGenerator(); 
	
	/**
	 * @return the group identity element 
	 */
	public abstract ElementGroup getGroupIdentityElement(); 

	/**
	 * @return the group order 
	 */
	public abstract java.math.BigInteger getGroupOrder(); 

	/**
	 * Generates a random array of elements belonging to the group.
	 * These elements are all generators since necessarily the group order is prime
	 * 
	 * @param arraySize - the number of generators requested
	 * @param pseudoGenerator - a PRG that generates random numbers
	 * @param seed - seed to give to the PRG
	 * @param error - the size of the statistical difference between two numbers
	 * @return an array of generators belonging to the group
	 * @throws Exception if arraySize is bigger than the group size or if PRG(seed) failed 
	 */
	public abstract ArrayOfElementGroup randomArray(int arraySize, PRG pseudoGenerator, byte[] seed, int error) throws Exception; 
	
}
